package net.wxxr.thread.pool;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

import net.wxxr.dataparse.model.DataParseCode;
import net.wxxr.http.interfaces.ITag;
import net.wxxr.http.response.HttpResponse;



/**
 * 自定义线程池，用来维护每任务
 * @author yuanwenfei
 * @param <T>
 */
public class ThreadGroup<T> {

	// 线程池的大小
	private final int CORE_POOL_SIZE;

	// 等待下载池的大小
	private final int MAX_POOL_SIZE;

	// 正在处理的队列
	private final List<TaskCommond> mProcessingQueue;

	// 等待队列的堆栈
	private final ArrayBlockingQueue<TaskCommond> mWaitingStack;

	// 线程ID标示
	private final AtomicInteger mCount = new AtomicInteger(1);

	// 同步锁标示
	private final Object mLock = new Object();

	// 标示该线程池是否已经关闭
	private boolean mShutdown = false;

	/**
	 * 创建一个线程池
	 * 
	 * @param corePoolSize
	 *            核心处理线程的个数
	 * @param maximumPoolSize
	 *            线程池中等待的线程个数
	 */
	public ThreadGroup(int corePoolSize, int maximumPoolSize) {
		CORE_POOL_SIZE = corePoolSize;
		MAX_POOL_SIZE = maximumPoolSize;

		mProcessingQueue = new ArrayList<TaskCommond>();
		mWaitingStack = new ArrayBlockingQueue<TaskCommond>(30);
	}
	
	/**
	 * 新建一个线程
	 * 
	 * @param task
	 * @return
	 */
	protected Thread newDataThread(final TaskCommond<T> commond) {
		Thread t = new Thread(new TaskRunnable(commond), "DataPool #" + this.mCount.getAndIncrement());
		t.setPriority(Thread.NORM_PRIORITY - 1);
		return t;
	}
	
	protected Thread newImageThread(final TaskCommond<T> commond) {
		Thread t = new Thread(new TaskRunnable(commond), "ImagePool #" + this.mCount.getAndIncrement());
		t.setPriority(Thread.NORM_PRIORITY - 1);
		return t;
	}

	/**
	 * 添加一个Http任务
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	public TaskCommond<T> addTask(TaskCommond<T> commond) {
		if (mShutdown) {
			System.err.println("线程池已经关闭！");
			return null;
		}
		synchronized (mLock) {
			if (mProcessingQueue.contains(commond) || mWaitingStack.contains(commond)) {
				return null;
			}

			int coreSize = mProcessingQueue.size();
			if (coreSize < CORE_POOL_SIZE) {
				
				// 说明核心正在处理的池子空闲，任务直接加入到核心池中
				mProcessingQueue.add(commond);
				Thread thread = newDataThread(commond);
				thread.start();
			} else {
				// 说明正在处理的池子繁忙，将任务加到等待队列中
				mWaitingStack.add(commond);

				if (mWaitingStack.size() > MAX_POOL_SIZE) {
					// 当等待队列超出最大值是，放入后进的任务，删除掉队首的第一个任务
					TaskCommond<T> removeTaskCommond = mWaitingStack.poll();
					ITag<T> removeTag = removeTaskCommond.getTask().getTag();
					// 被挤出去的任务，执行fail接口
					removeTaskCommond.getResponse().failed(removeTag, DataParseCode.THREAD_POOL_FULL);
				}
			}
		}
		return commond;
	}

	/**
	 * 取消一条任务
	 * 
	 * @param task
	 */
	public void cancelTask(TaskCommond<T> commond) {
		synchronized (mLock) {
			// 核心处理队列中设置Cancel标志位
			if (mProcessingQueue.contains(commond)) {
				commond.getTask().getRequest().cancel();
			}

			// 等待队列中，直接移除任务
			if (mWaitingStack.contains(commond)) {
				mWaitingStack.remove(commond);
				return;
			}
		}
	}

	/**
	 * 取消所有任务
	 * 
	 * @param task
	 */
	public void cancelAllTask() {
		synchronized (mLock) {
			mWaitingStack.clear();

			for (TaskCommond<T> commond : mProcessingQueue) {
				commond.getTask().getRequest().cancel();
			}
			mProcessingQueue.clear();
		}
	}

	/**
	 * 关闭线程池，关闭后将无法再次开启
	 */
	public void shutdown() {
		mShutdown = true;
		cancelAllTask();
	}

	/**
	 * 从等待的任务栈中取出一条任务
	 * 
	 * @return
	 */
	private TaskCommond<T> popTaskFromStack() {
		synchronized (mLock) {
			if (mShutdown) {
				System.err.println("线程池已经关闭！");
				return null;
			}

			if (mWaitingStack.size() == 0) {
				return null;
			}

			TaskCommond<T> commond = mWaitingStack.poll();
			return commond; 
		}
	}

	private class TaskRunnable implements Runnable {

		//private Task<T> task;
        private TaskCommond<T>  commond;
        
		public TaskRunnable(TaskCommond<T> commond) {
			super();
			this.commond = commond;
		}

		@Override
		public void run() {
			do {
				
				commond.execute();
				
			} while (isTrue());

			synchronized (mLock) {
				//队列中没有可执行任务时,删除当前的任务
				mProcessingQueue.remove(commond);
			}
		}

		private boolean isTrue() { 
			synchronized (mLock) {
				
				TaskCommond<T> newCommond = popTaskFromStack();
				//从队列顶部获得一个等待任务
				if (newCommond != null) {
					mProcessingQueue.remove(commond);
					commond = newCommond;
					mProcessingQueue.add(commond);
					return true;
				}
				return false;
			}
		}
		
	}
}
